package ruler.main;

import java.util.ArrayList;
import java.util.List;

import ruler.rules.Rule;
import ruler.rules.Rule.DEVICE_TYPE;
import ruler.rules.storage.RulesHash;
import ruler.rules.storage.RulesStore;
import ruler.services.RulerService;
import ruler.services.RulerServiceBinder;
import ruler.services.RulerServiceConnection;
import android.app.ActivityManager;
import android.app.Application;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class WifiGPSRulerApplication extends Application {

	private static final String RULER_APPLICATION_TAG = "WifiGPSRulerApplication";
	private static RulerServiceConnection serviceConnection;
	private static RulerServiceBinder serviceBinder;
	private static boolean serviceStarted = false;

	private static RulesHash rules;

	@Override
	public void onCreate() {
		super.onCreate();
		rules = RulesStore.Load();
		initRulerService();
	}

	@Override
	public void onTerminate() {
		super.onTerminate();
		releaseService();
	}

	private void initRulerService() {
		if (isRulerServiceRunning())
			connectToService();
		else
			startService();
	}

	private void connectToService() {
		if (serviceConnection == null) {
			serviceConnection = new RulerServiceConnection(this);
			bindService(new Intent(this, RulerService.class),
					serviceConnection, Context.BIND_AUTO_CREATE);
			serviceStarted = true;
		} else {
			Log.v(RULER_APPLICATION_TAG,
					getResources().getString(R.string.alreadyConnected));
		}
	}

	public void startService() {
		if (!serviceStarted) {
			startService(new Intent(this, RulerService.class));
			serviceStarted = true;
			connectToService();
			showServiceStatus();
		} else {
			Toast.makeText(this,
					getResources().getString(R.string.alreadyStarted),
					Toast.LENGTH_SHORT).show();
		}
	}

	public void stopService() {
		if (serviceStarted) {
			releaseService();
			stopService(new Intent(this, RulerService.class));
			serviceStarted = false;
			showServiceStatus();
		} else {
			Toast.makeText(this, getResources().getString(R.string.notStarted),
					Toast.LENGTH_SHORT).show();
		}
	}

	private void releaseService() {
		if (serviceConnection != null) {
			unbindService(serviceConnection);
			serviceConnection = null;
			serviceBinder = null;
		} else {
			Log.v(RULER_APPLICATION_TAG,
					getResources().getString(R.string.notConnected));
		}
	}

	public void restartService() {
		if (serviceBinder != null) {
			serviceBinder.getService().restartService();
			Toast.makeText(this,
					getResources().getString(R.string.serviceRestarted),
					Toast.LENGTH_SHORT).show();
		} else {
			initRulerService();
		}
	}

	private boolean isRulerServiceRunning() {
		ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
		for (RunningServiceInfo service : manager
				.getRunningServices(Integer.MAX_VALUE)) {
			if ("ruler.services.RulerService".equals(service.service
					.getClassName())) {
				return true;
			}
		}
		return false;
	}

	public void showServiceStatus() {
		String bindStatus = serviceConnection == null ? "unbound" : "bound";
		String startStatus = serviceStarted ? "started" : "not started";
		String statusText = "Service status: " + bindStatus + "," + startStatus;
		Toast.makeText(this, statusText, Toast.LENGTH_SHORT).show();
	}

	public RulerServiceBinder getServiceBinder() {
		return serviceBinder;
	}

	public void setServiceBinder(RulerServiceBinder service) {
		WifiGPSRulerApplication.serviceBinder = service;
	}

	public List<Rule> getRules(DEVICE_TYPE deviceType, boolean deviceState) {
		return rules.getRules(deviceType, deviceState);
	}

	public void addRule(Rule r) {
		if (r != null)
			rules.addRule(r);
	}

	public void removeRule(Rule r) {
		if (r != null)
			rules.removeRule(r.getName(), r.getDeviceType(),
					r.getDeviceEnable());
	}

	public void saveRules() {
		RulesStore.Save(rules);
		restartService();
	}
	
	public ArrayList<Rule> getAllRules(){
		return rules.getAllRules();
	}
}
